package javabase.demo03;

public class ThreadSafetyIssues {

    private static  int count = 0; // 共享变量
    private static  volatile boolean flag = false; // volatile测试
    private static int a = 0, b = 0, x = 0, y = 0; // 指令重排测试

    public static void main(String[] args) throws InterruptedException {
        // 1. 原子性问题演示
        demonstrateAtomicityIssue();

        // 2. 可见性问题演示
        demonstrateVisibilityIssue();

        // 3. 有序性问题演示
        demonstrateOrderingIssue();
    }

    // 原子性问题：count++不是原子操作
    private static void demonstrateAtomicityIssue() throws InterruptedException {

        System.out.println("\n=== 原子性问题演示 ===");
        count = 0;
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 10000; i++) {
                    count++;
                }
            }
        });
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 10000; i++) {
                count++;
            }
        });
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println("期望值: 20000, 实际值: " + count);
    }

    // 可见性问题：一个线程修改了变量，另一个线程可能看不到
    private static void demonstrateVisibilityIssue() throws InterruptedException {
        System.out.println("\n=== 可见性问题演示 ===");
        flag = false;
        // 线程1：修改flag
        Thread t1 = new Thread(() -> {
            try {
                Thread.sleep(100); // 确保线程2先运行
                flag = true;
                System.out.println("线程1设置flag为true");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        // 线程2：循环读取flag
        Thread t2 = new Thread(() -> {
            while (!flag) {
                // 空循环，等待flag变为true
            }
            System.out.println("线程2检测到flag为true");
        });

        t2.start();
        t1.start();

        t1.join();
        t2.join();
    }

    // 有序性问题：指令重排可能导致意外结果
    private static void demonstrateOrderingIssue() throws InterruptedException {
        System.out.println("\n=== 有序性问题演示 ===");
        int detected = 0;
        for (int i = 0; i < 200000; i++) {
            a = 0; b = 0; x = 0; y = 0;

            Thread t1 = new Thread(() -> {
                a = 1; // 语句1
                x = b; // 语句2
            });

            Thread t2 = new Thread(() -> {
                b = 1; // 语句3
                y = a; // 语句4
            });

            t1.start();
            t2.start();
            t1.join();
            t2.join();

            // 如果没有指令重排，x和y不可能同时为0
            if (x == 0 && y == 0) {
                detected++;
                System.out.println("检测到指令重排: x=" + x + ", y=" + y + ",detected=" + detected);
                break;
            }
        }
        if (detected == 0) {
            System.out.println("未检测到指令重排");
        }
    }
}
